package ggroubig

import (
	"sync"
	"sync/atomic"
	"wzgames/internal/codec/sfs"
	"wzgames/internal/response"
	"wzgames/internal/services/games"
	"wzgames/pkg/logger"
)

// 播报通知分组

type Notifier struct {
	mu      sync.RWMutex
	msgChan chan interface{}
	stopCh  chan struct{}
	mapGt   map[uint64]*games.GameTable // 玩家登录游戏注册
	cl      int32
}

func newNotifier(chanSize int64) *Notifier {
	nt := &Notifier{
		msgChan: make(chan interface{}, chanSize),
		stopCh:  make(chan struct{}, 1),
		mapGt:   make(map[uint64]*games.GameTable),
	}
	go nt.Run()
	return nt
}

func (nt *Notifier) Notify(msg interface{}) {
	if atomic.LoadInt32(&nt.cl) == 1 {
		return
	}
	nt.msgChan <- msg
}

func (nt *Notifier) Run() {
	defer logger.RecoverPanic()
	for {
		select {
		case m := <-nt.msgChan:
			nt.broadcast(m)

			if v, ok := m.(*sfs.RawPacket); ok {
				response.ReleaseMsgO(v)
			}
		case <-nt.stopCh:
			return
		}
	}
}

func (nt *Notifier) broadcast(msg interface{}) {
	nt.mu.RLock()
	defer nt.mu.RUnlock()

	v, ok := msg.(*sfs.RawPacket)
	for _, gt := range nt.mapGt {
		if gt != nil {
			if ok {
				m := response.AcquireMsgO()
				m.Id = v.Id
				m.ControlId = v.ControlId
				m.Write(v.Content)
				gt.Sess.Send(m)
			} else {
				gt.Sess.Send(msg)
			}
		}
	}
}

func (nt *Notifier) Register(tb *games.GameTable) {
	nt.mu.Lock()
	nt.mapGt[tb.Player.ID()] = tb
	nt.mu.Unlock()
}

func (nt *Notifier) Unregister(playerId uint64) {
	nt.mu.Lock()
	delete(nt.mapGt, playerId)
	nt.mu.Unlock()
}

func (nt *Notifier) Close() {
	atomic.StoreInt32(&nt.cl, 1)
	//close(nt.msgChan)
	nt.stopCh <- struct{}{}
	close(nt.stopCh)
}
